#pragma once

#include <string>
#include <memory>
#include <mutex>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/fmt/ostr.h>
#include <ctime>

// 日志配置结构体
struct LoggerConfig {
    std::string baseFileName;        // 基础文件名
    size_t maxFileSize = 10485760;   // 单个文件最大大小，默认10MB
    size_t maxFiles = 5;             // 最大文件数量
    bool consoleOutput = true;       // 是否输出到控制台
    spdlog::level::level_enum level = spdlog::level::info;  // 日志级别
};

class Logger {
public:
    // 初始化日志系统
    static void init(const LoggerConfig& config);

    // 清理资源
    static void cleanup();

    // 获取日志器
    static std::shared_ptr<spdlog::logger> getLogger();

    // 日志级别设置
    static void setLevel(spdlog::level::level_enum level);

    // 日志记录接口
    template<typename... Args>
    static void trace(const char* file, const char* func, int line, const Args&... args) {
        if (getLogger()) getLogger()->trace("[{}:{}:{}] {}", extractFileName(file), func, line, fmt::format(args...));
    }

    template<typename... Args>
    static void debug(const char* file, const char* func, int line, const Args&... args) {
        if (getLogger()) getLogger()->debug("[{}:{}:{}] {}", extractFileName(file), func, line, fmt::format(args...));
    }

    template<typename... Args>
    static void info(const char* file, const char* func, int line, const Args&... args) {
        if (getLogger()) getLogger()->info("[{}:{}:{}] {}", extractFileName(file), func, line, fmt::format(args...));
    }

    template<typename... Args>
    static void warn(const char* file, const char* func, int line, const Args&... args) {
        if (getLogger()) getLogger()->warn("[{}:{}:{}] {}", extractFileName(file), func, line, fmt::format(args...));
    }

    template<typename... Args>
    static void error(const char* file, const char* func, int line, const Args&... args) {
        if (getLogger()) getLogger()->error("[{}:{}:{}] {}", extractFileName(file), func, line, fmt::format(args...));
    }

    template<typename... Args>
    static void critical(const char* file, const char* func, int line, const Args&... args) {
        if (getLogger()) getLogger()->critical("[{}:{}:{}] {}", extractFileName(file), func, line, fmt::format(args...));
    }

private:
    static std::shared_ptr<spdlog::logger> logger;
    static std::once_flag initFlag;
    static std::mutex mutex;

    // 提取文件名（不含路径）
    static std::string extractFileName(const std::string& filePath);

    // 生成带时间戳的文件名
    static std::string generateTimestampedFileName(const std::string& baseName);
};

// 定义日志宏，自动获取文件、函数和行号信息
#define LOG_TRACE(...) Logger::trace(__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
#define LOG_DEBUG(...) Logger::debug(__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
#define LOG_INFO(...)  Logger::info(__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
#define LOG_WARN(...)  Logger::warn(__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
#define LOG_ERROR(...) Logger::error(__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
#define LOG_CRITICAL(...) Logger::critical(__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
